package util

import (
	"flag"
	"fmt"
	"image"
	"image/draw"
	"image/jpeg"
	"image/png"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/chai2010/webp"
	"github.com/disintegration/imaging"
	raylib "github.com/gen2brain/raylib-go/raylib"
	"github.com/kbinani/screenshot"
	"golang.org/x/image/bmp"
)

var (
	selectionStartX, selectionStartY int
	selectionEndX, selectionEndY     int
	selecting                        bool
	screenImg                        image.Image
	screenTexture                    raylib.Texture2D
)

func ShowHelp() {
	fmt.Println("go-scrot - 屏幕截图工具")
	fmt.Println("Usage: go-scrot [options]")
	fmt.Println("Options:")
	flag.PrintDefaults()

}

// 定义一个可比较的类型约束
type Ordered interface {
	int | int8 | int16 | int32 | int64 |
		uint | uint8 | uint16 | uint32 | uint64 | uintptr |
		float32 | float64 |
		string
}

// Min 函数返回两个可比较类型中的较小值
func Min[T Ordered](a, b T) T {
	if a < b {
		return a
	}
	return b
}

// Max 函数返回两个可比较类型中的较大值
func Max[T Ordered](a, b T) T {
	if a > b {
		return a
	}
	return b
}

// 确保目录存在
func EnsureDir(filePath string) error {
	// 提取文件路径中的目录部分
	dir := filepath.Dir(filePath)

	if _, err := os.Stat(dir); os.IsNotExist(err) {
		return os.MkdirAll(dir, 0755)
	}
	return nil
}

// 生成默认文件名
func GenerateDefaultFileName(format string) string {
	timestamp := time.Now().Format("2006-01-02_15-04-05")

	dir, err := os.Getwd()
	if err != nil {
		dir = "."
	}
	prefix := "screenshot"
	return filepath.Join(dir, fmt.Sprintf("%s_%s.%s", prefix, timestamp, format))
}

// 保存图片
func SaveImage(img image.Image, filePath, format string) error {
	// 检查路径是否是一个已存在的目录
	if info, err := os.Stat(filePath); err == nil && info.IsDir() {
		return fmt.Errorf("指定的路径 %s 是一个目录，而不是文件", filePath)
	}

	// 确保目录存在
	if err := EnsureDir(filePath); err != nil {
		return fmt.Errorf("创建目录失败: %v", err)
	}

	file, err := os.Create(filePath)
	if err != nil {
		return fmt.Errorf("创建文件失败: %v", err)
	}
	defer file.Close()

	// 将image.Image转换为NRGBA格式，以支持所有图像操作
	if img != nil {
		bounds := img.Bounds()
		rgba := image.NewRGBA(bounds)
		draw.Draw(rgba, bounds, img, bounds.Min, draw.Src)
		img = rgba
	}

	switch strings.ToLower(format) {
	case "png":
		return png.Encode(file, img)
	case "jpg", "jpeg":
		return jpeg.Encode(file, img, &jpeg.Options{
			Quality: 95,
		})
	case "bmp":
		return bmp.Encode(file, img)
	case "webp":
		// 使用chai2010/webp库编码WebP
		return webp.Encode(file, img, &webp.Options{
			Quality: 80, // 默认质量
		})
	case "tiff":
		// 使用golang.org/x/image/tiff库编码TIFF
		// return tiff.Encode(file, img, &tiff.Options{
		// Compression: tiff.Deflate,
		// Predictor:   true,
		// })
		return imaging.Save(img, filePath)
	default:
		return fmt.Errorf("不支持的格式: %s", format)
	}
}

// 捕获屏幕
func CaptureScreen() (image.Image, error) {
	n := screenshot.NumActiveDisplays()
	if n <= 0 {
		return nil, fmt.Errorf("no active displays")
	}

	bounds := screenshot.GetDisplayBounds(0)
	img, err := screenshot.CaptureRect(bounds)
	if err != nil {
		return nil, fmt.Errorf("capture screen error: %v", err)
	}
	return img, nil
}

// 捕获屏幕选择区域
func CaptureScreenSelection() (image.Image, error) {
	fmt.Println("请选择屏幕区域...")
	var err error
	screenImg, err = CaptureScreen()
	if err != nil {
		return nil, fmt.Errorf("capture screen error: %v", err)
	}

	screenBounds := screenImg.Bounds()
	raylib.InitWindow(int32(screenBounds.Dx()), int32(screenBounds.Dy()), "选择截图区域")
	defer raylib.CloseWindow()

	raylib.ToggleFullscreen()

	screenTexture = CreateTextureFromImage(screenImg)
	defer raylib.UnloadTexture(screenTexture)

	selecting = false

	for !raylib.WindowShouldClose() {
		if raylib.IsMouseButtonPressed(raylib.MouseLeftButton) {
			selecting = true
			selectionStartX, selectionStartY = int(raylib.GetMouseX()), int(raylib.GetMouseY())
			selectionEndX, selectionEndY = selectionStartX, selectionStartY
		}
		if selecting {
			selectionEndX, selectionEndY = int(raylib.GetMouseX()), int(raylib.GetMouseY())
		}

		if raylib.IsKeyPressed(raylib.KeyEnter) && selecting {
			break
		}

		raylib.BeginDrawing()
		raylib.DrawTexture(screenTexture, 0, 0, raylib.White)

		if selecting {
			x := Min(selectionStartX, selectionEndX)
			y := Min(selectionStartY, selectionEndY)

			width := Max(selectionStartX, selectionEndX) - x
			height := Max(selectionStartY, selectionEndY) - y

			raylib.DrawRectangleLines(int32(x), int32(y), int32(width), int32(height), raylib.NewColor(0, 255, 0, 255))
			raylib.DrawText("按Enter键确认截图", int32(x), int32(y-20), 16, raylib.NewColor(0, 255, 0, 255))

		} else {
			raylib.DrawText("请选择截图区域", int32(10), int32(10), 20, raylib.NewColor(0, 255, 0, 255))
		}

		raylib.EndDrawing()
	}

	x := Min(selectionStartX, selectionEndX)
	y := Min(selectionStartY, selectionEndY)
	width := Max(selectionStartX, selectionEndX) - x
	height := Max(selectionStartY, selectionEndY) - y

	if width <= 0 || height <= 0 {
		return nil, fmt.Errorf("选择的区域无效")
	}

	selectedRegion := image.NewRGBA(image.Rect(0, 0, width, height))
	draw.Draw(selectedRegion, selectedRegion.Bounds(), screenImg, image.Point{x, y}, draw.Src)
	return selectedRegion, nil
}
